Cryptext64 Vault Blob v1 - DRAFT / 0.11l persistent A/B test layer
===================================================

Storage:
  HKCU\Software\Cryptext64\Vault
  Value names: VaultA, VaultB
  Type: REG_BINARY

The Registry is treated as publicly readable storage, not as cryptographic
protection. Both slots contain complete blobs.

Fixed header (0x90 bytes)
-------------------------
Offset Size  Meaning
0x00   4     Magic bytes "VLT1"
0x04   4     Format version = 1
0x08   4     Header bytes = 0x90
0x0C   4     Total blob bytes
0x10   8     Generation (u64)
0x18   4     Flags = 0 for v1
0x1C   4     KDF ID = 1 (PBKDF2-HMAC-SHA-256)
0x20   4     KDF iterations (stored per blob)
0x24   4     Cipher ID = 1 (AES-256-GCM)
0x28   4     Offset of DPAPI-protected DeviceSecret
0x2C   4     Bytes of DPAPI-protected DeviceSecret
0x30   4     Offset of wrapped VaultKey ciphertext
0x34   4     Wrapped VaultKey bytes = 32
0x38   4     Offset of encrypted Cryptext-password ciphertext
0x3C   4     Password ciphertext bytes (UTF-16LE byte count)
0x40   16    Public KDF salt
0x50   12    AES-GCM nonce for VaultKey wrapping
0x5C   16    AES-GCM tag for VaultKey wrapping
0x6C   12    AES-GCM nonce for password encryption
0x78   16    AES-GCM tag for password encryption
0x88   8     Reserved = 0 in v1

Payload (canonical, no gaps, no trailing bytes)
------------------------------------------------
header 0x90
DPAPI(DeviceSecret[32])    variable length, <= 2048 bytes in v1 parser
WrappedVaultKey            exactly 32 ciphertext bytes
EncryptedCryptextPassword  2..1022 bytes, even UTF-16LE length, no NUL stored

AAD plan
--------
Bytes 0x00..0x4F (80 bytes) are the fixed non-secret metadata authenticated as
AAD by the future AES-GCM operations. Nonces are supplied through GCM itself;
tags are not part of their own AAD.

Key hierarchy exercised by 0.11k/0.11l
---------------------------------
  DeviceSecret = random 32 bytes, persisted only as current-user DPAPI blob
  PIN           = 4..6 decimal digits, user input
  KEK           = PBKDF2-HMAC-SHA-256(PIN, public Salt + DeviceSecret)
  VaultKey      = random 32 bytes, wrapped with KEK / AES-256-GCM
  Secret        = real long Cryptext password, encrypted with VaultKey / GCM

The VaultKey is NOT a CT64FILE-v1 file key. CT64FILE v1 continues to receive the
same real Cryptext password as manual input and remains fully vault-independent.

A/B rule
--------
A slot's Generation is never trusted from structural parsing alone. A future
reader must successfully:
  1. parse the complete slot,
  2. unprotect DeviceSecret with DPAPI,
  3. derive KEK from the supplied PIN,
  4. authenticate/decrypt wrapped VaultKey,
  5. authenticate/decrypt the stored Cryptext password,
before that slot's Generation may participate in choosing the newest slot.


0.11l implementation status
---------------------------
0.11k proved the complete key hierarchy in RAM. 0.11l adds a persistent
development A/B test under the final HKCU key, but deliberately uses the value
names VaultTestA and VaultTestB. Production VaultA/VaultB are still untouched.

Each successful 0.11l test:
  1. reads both development slots,
  2. structurally validates candidates,
  3. DPAPI-unprotects DeviceSecret,
  4. derives the PIN KEK,
  5. authenticates/decrypts both GCM layers,
  6. only then reads/compares Generation,
  7. writes the next Generation to the other A/B test slot,
  8. reads the complete REG_BINARY back byte-for-byte,
  9. performs full cryptographic authentication on the independent readback,
 10. re-reads both slots and proves the new authenticated Generation wins.

If structurally valid test data exists but neither slot authenticates with the
supplied PIN, the test refuses to overwrite it. The real Cryptext password is
still not stored and CT64FILE v1 remains byte-for-byte independent.
